package FreebaseMatchWiki;

import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import java.util.*;

/**
 * select T.type, T.prop, T.value from type T, guid_wpid G where G.wpid=12 AND
 * G.guid=T.guid For Anarchism
 */
public class ExtractFBTypeValue {

	static HashMap<String, Integer> typeprop_id = new HashMap<String, Integer>();
	static int MAXAllowMatchOneProperty = 10;
	static int MAXAllowPropNumber = 10; // I only allow one property has **
										// values, if it has more than that
										// value, there is no hope to match in
										// context

	public static void load_typeprop_id(String file) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(
				new FileInputStream(file)));
		String line = "";
		int ln = 1;
		while ((line = br.readLine()) != null) {
			String[] abc = line.split("\\s");
			String typeprop = abc[1] + "\t" + abc[2];
			typeprop_id.put(typeprop, ln++);
		}
	}

	/**
	 * @param args
	 */
	// main_main
	public static void main_main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		load_typeprop_id(args[2]);
		String rphid_wpid_file = args[0];
		String sentence_file = args[1];
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
				args[3]), "utf-8");
		BufferedReader br = new BufferedReader(new FileReader(rphid_wpid_file));
		BufferedReader brsen = new BufferedReader(new InputStreamReader(
				new FileInputStream(sentence_file), "utf-8"));
		String line = "";
		MyDB mydb = new MyDB();
		String line2 = "";

		ArrayList<String[]> block = new ArrayList<String[]>();
		String[] buffer = null;
		int ln = 0;
		while ((line = br.readLine()) != null) {

			// line = br.readLine();

			ln++;
			if (ln % 100 == 0)
				System.out.print(".");
			if (ln % 10000 == 0)
				System.out.println((new java.util.Date()).toString() + "  "
						+ ln);
			// line = "240	736	Albert Einstein";
			String[] abc = line.split("\t");
			int rphid = Integer.parseInt(abc[0]);
			int wpid = Integer.parseInt(abc[1]);
			String title = abc[2];

			block.clear();
			if (buffer != null
					&& Integer
							.parseInt(buffer[raphaelMatcher.CreateSentencesSchema.cs_articleId]) == wpid) {
				block.add(buffer);
			}
			while ((line2 = brsen.readLine()) != null) {
				String[] sensplit = line2.split("\t");
				int senrphid = Integer
						.parseInt(sensplit[raphaelMatcher.CreateSentencesSchema.cs_articleId]);

				if (senrphid == rphid) {
					block.add(sensplit);
				} else if (senrphid > rphid) {
					buffer = sensplit;
					break;
				}
			}

			ArrayList<TypePropValue> tpvlist = mydb.getTypePropValueWithWpid(
					wpid, abc[2]);

			// for debug
			// for (String[] sensplit : block) {
			// String sentence =
			// sensplit[raphaelMatcher.CreateSentencesSchema.cs_sentence];
			// osw.write(sentence + "\n");
			// }
			// osw
			// .write("----------------------------------------------------------------------------------------------------------------------\n");
			//
			// for (TypePropValue tpv : tpvlist) {
			// osw.write(tpv.type + "\t" + tpv.prop + "\t" + tpv.value + "\n");
			//
			// }
			// osw
			// .write("----------------------------------------------------------------------------------------------------------------------\n");

			for (TypePropValue tpv : tpvlist) {
				ArrayList<String> toWrite = new ArrayList<String>();
				for (String[] sensplit : block) {
					String value = tpv.value;
					String sentence = sensplit[raphaelMatcher.CreateSentencesSchema.cs_sentence];
					int senid = Integer
							.parseInt(sensplit[raphaelMatcher.CreateSentencesSchema.cs_sentenceId]);
					ArrayList<Integer> matchPos = strictAndCapitalMatch(value,
							sentence, title);
					if (matchPos != null && matchPos.size() > 0) {
						toWrite.add(rphid + "\t" + wpid + "\t" + senid + "\t"
								+ tpv.type + "\t" + tpv.prop + "\t" + matchPos
								+ "\t" + value);
						if (toWrite.size() > MAXAllowMatchOneProperty) {
							break;
						}
						// osw.write(rphid+"\t"+wpid+"\t"+senid+"\t"+tpv.type +
						// "\t" + tpv.prop + "\t" + matchPos
						// + "\t" + value + "\n");
						// String toWrite = formatOutput(rphid, wpid, senid,
						// tpv, matchPos);
						// if(toWrite!=null){
						// osw.write(toWrite+"\n");
						// }
					}
				}
				if (toWrite.size() <= MAXAllowMatchOneProperty) {
					for (String a : toWrite)
						osw.write(a + "\n");
				}
			}
			// break;
		}
		br.close();
		osw.close();
	}

	public static ArrayList<Integer> strictMatch(String value, String sentence) {

		ArrayList<Integer> res = new ArrayList<Integer>();
		String[] abc = value.toLowerCase().split("\\|");
		sentence = sentence.toLowerCase();
		boolean completeMatch = true;
		for (int i = 0; i < abc.length; i++) {
			int a = sentence.indexOf(abc[i]);
			if (a >= 0) {
				res.add(a);
				// System.out.println(value+"\t"+sentence);
			} else {
				completeMatch = false;
				break;
			}
		}
		if (completeMatch) {
			return res;
		} else {
			return null;
		}
	}

	public static ArrayList<Integer> strictAndCapitalMatch(String value,
			String sentence, String title) {

		ArrayList<Integer> res = new ArrayList<Integer>();
		String[] abc = value.split("\\|");
		sentence = sentence.toLowerCase();
		boolean matchCaptialLetter = false;
		if (abc.length > MAXAllowPropNumber) {
			return null;
		}
		for (int i = 0; i < abc.length; i++) {
			int a = sentence.indexOf(abc[i].toLowerCase());

			if (a >= 0) {
				res.add(a);
				String[] aa = abc[i].split("\\s");
				// if contain capital letter && title not contain that word &&
				// abc[i] contain at least two words
				boolean abciLonger5 = abc[i].length() > 5;
				if (!abc[i].equals(abc[i].toLowerCase())
						&& !title.contains(abc[i]) && abciLonger5) {
					matchCaptialLetter = true;
				}
				// System.out.println(value+"\t"+sentence);
			} else {
				res.add(-1);
			}
		}
		boolean allMatch = true;
		for (int a : res) {
			if (a == -1)
				allMatch = false;
		}
		if (matchCaptialLetter || allMatch) {
			return res;
		} else
			return null;
	}

	// main_debug_one
	public static void main_debug_one(String[] args) throws Exception {
		// TODO Auto-generated method stub
		load_typeprop_id(args[2]);
		String rphid_wpid_file = args[0];
		String sentence_file = args[1];
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
				"temp2"), "utf-8");
		BufferedReader br = new BufferedReader(new FileReader(rphid_wpid_file));
		BufferedReader brsen = new BufferedReader(new InputStreamReader(
				new FileInputStream(sentence_file), "utf-8"));
		String line = "";
		MyDB mydb = new MyDB();
		String line2 = "";

		ArrayList<String[]> block = new ArrayList<String[]>();
		String[] buffer = null;
		while ((line = br.readLine()) != null) {
			line = "240	736	Albert Einstein";
			String[] abc = line.split("\t");
			int rphid = Integer.parseInt(abc[0]);
			int wpid = Integer.parseInt(abc[1]);
			String title = abc[2];
			block.clear();
			if (buffer != null
					&& Integer
							.parseInt(buffer[raphaelMatcher.CreateSentencesSchema.cs_articleId]) == wpid) {
				block.add(buffer);
			}
			while ((line2 = brsen.readLine()) != null) {
				String[] sensplit = line2.split("\t");
				int senrphid = Integer
						.parseInt(sensplit[raphaelMatcher.CreateSentencesSchema.cs_articleId]);

				if (senrphid == rphid) {
					block.add(sensplit);
				} else if (senrphid > rphid) {
					buffer = sensplit;
					break;
				}
			}

			ArrayList<TypePropValue> tpvlist = mydb.getTypePropValueWithWpid(
					wpid, abc[2]);

			// for debug
			for (String[] sensplit : block) {
				String sentence = sensplit[raphaelMatcher.CreateSentencesSchema.cs_sentence];
				osw.write(sentence + "\n");
			}
			osw
					.write("----------------------------------------------------------------------------------------------------------------------\n");

			for (TypePropValue tpv : tpvlist) {
				osw.write(tpv.type + "\t" + tpv.prop + "\t" + tpv.value + "\n");

			}
			osw
					.write("----------------------------------------------------------------------------------------------------------------------\n");

			for (TypePropValue tpv : tpvlist) {
				for (String[] sensplit : block) {
					String value = tpv.value;
					String sentence = sensplit[raphaelMatcher.CreateSentencesSchema.cs_sentence];
					int senid = Integer
							.parseInt(sensplit[raphaelMatcher.CreateSentencesSchema.cs_sentenceId]);
					ArrayList<Integer> matchPos = strictAndCapitalMatch(value,
							sentence, title);
					if (matchPos != null && matchPos.size() > 0) {
						osw.write(tpv.type + "\t" + tpv.prop + "\t" + matchPos
								+ "\t" + value + "\t" + sentence + "\n");
						System.out.println(formatOutput(rphid, wpid, senid,
								tpv, matchPos));
					}
				}
			}
			break;
		}
		br.close();
		osw.close();
	}

	// main_debug
	public static void main_debug(String[] args) throws Exception {
		// TODO Auto-generated method stub
		load_typeprop_id(args[2]);
		String rphid_wpid_file = args[0];
		String sentence_file = args[1];
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(
				"temp"), "utf-8");
		BufferedReader br = new BufferedReader(new FileReader(rphid_wpid_file));
		BufferedReader brsen = new BufferedReader(new InputStreamReader(
				new FileInputStream(sentence_file), "utf-8"));
		String line = "";
		MyDB mydb = new MyDB();
		String line2 = "";

		ArrayList<String[]> block = new ArrayList<String[]>();
		String[] buffer = null;
		int ln = 0;
		while ((line = br.readLine()) != null && ln < 1000) {
			ln++;
			if (ln % 10 == 0)
				System.out.print(".");
			if (ln % 1000 == 0)
				System.out.println((new java.util.Date()).toString());
			// line = "240	736	Albert Einstein";
			String[] abc = line.split("\t");
			int rphid = Integer.parseInt(abc[0]);
			int wpid = Integer.parseInt(abc[1]);
			String title = abc[2];

			block.clear();
			if (buffer != null
					&& Integer
							.parseInt(buffer[raphaelMatcher.CreateSentencesSchema.cs_articleId]) == wpid) {
				block.add(buffer);
			}
			while ((line2 = brsen.readLine()) != null) {
				String[] sensplit = line2.split("\t");
				int senrphid = Integer
						.parseInt(sensplit[raphaelMatcher.CreateSentencesSchema.cs_articleId]);

				if (senrphid == rphid) {
					block.add(sensplit);
				} else if (senrphid > rphid) {
					buffer = sensplit;
					break;
				}
			}

			ArrayList<TypePropValue> tpvlist = mydb.getTypePropValueWithWpid(
					wpid, abc[2]);

			// for debug
			// for (String[] sensplit : block) {
			// String sentence =
			// sensplit[raphaelMatcher.CreateSentencesSchema.cs_sentence];
			// osw.write(sentence + "\n");
			// }
			// osw
			// .write("----------------------------------------------------------------------------------------------------------------------\n");
			//
			// for (TypePropValue tpv : tpvlist) {
			// osw.write(tpv.type + "\t" + tpv.prop + "\t" + tpv.value + "\n");
			//
			// }
			// osw
			// .write("----------------------------------------------------------------------------------------------------------------------\n");

			for (TypePropValue tpv : tpvlist) {
				ArrayList<String> toWrite = new ArrayList<String>();
				for (String[] sensplit : block) {
					String value = tpv.value;
					String sentence = sensplit[raphaelMatcher.CreateSentencesSchema.cs_sentence];
					int senid = Integer
							.parseInt(sensplit[raphaelMatcher.CreateSentencesSchema.cs_sentenceId]);
					ArrayList<Integer> matchPos = strictAndCapitalMatch(value,
							sentence, title);
					if (matchPos != null && matchPos.size() > 0) {
						toWrite.add(rphid + "\t" + wpid + "\t" + senid + "\t"
								+ tpv.type + "\t" + tpv.prop + "\t" + matchPos
								+ "\t" + value + "\t" + sentence);
						if (toWrite.size() > MAXAllowMatchOneProperty) {
							break;
						}
						// osw.write(rphid+"\t"+wpid+"\t"+senid+"\t"+tpv.type +
						// "\t" + tpv.prop + "\t" + matchPos
						// + "\t" + value + "\n");
						// String toWrite = formatOutput(rphid, wpid, senid,
						// tpv, matchPos);
						// if(toWrite!=null){
						// osw.write(toWrite+"\n");
						// }
					}
				}
				if (toWrite.size() <= MAXAllowMatchOneProperty) {
					for (String a : toWrite)
						osw.write(a + "\n");
				}
			}
			// break;
		}
		br.close();
		osw.close();
	}

	public static String formatOutput(int rphId, int wpid, int sentenceId,
			TypePropValue tpv, ArrayList<Integer> matchpos) {
		int propid = -1;
		try {
			propid = typeprop_id.get(tpv.type + "\t" + tpv.prop);
			return rphId + "\t" + wpid + "\t" + sentenceId + "\t" + propid
					+ "\t" + matchpos.toString();
		} catch (Exception e) {
			// e.printStackTrace();
		}
		return null;

	}



}
